use std::sync::{Arc, Mutex};
use tokio::sync::mpsc::{Sender, Receiver, unbounded_channel, channel};
use crate::context::Context;
use crate::message::Message;
use crate::actors::Actor;
use crate::mailbox::{MailboxSender, MailboxType};
use futures::future::BoxFuture;
use futures::FutureExt;

// 定义 TokioMailbox
pub struct TokioMailbox {
    sender: Sender<Box<dyn Message>>,
}

impl TokioMailbox {
    pub fn new(actor: Arc<Mutex<dyn Actor + Send>>, mailbox_type: MailboxType) -> Self {
        let (sender, mut receiver) = match mailbox_type {
            MailboxType::Unbounded => unbounded_channel(),
            MailboxType::Bounded(size) => channel(size),
        };
        let actor_clone = actor.clone();
        tokio::spawn(async move {
            let context = Context::new(receiver);
            while let Some(msg) = context.receiver.recv().await {
                let mut actor = actor_clone.lock().unwrap();
                actor.receive(&context, msg);
            }
        });

        TokioMailbox { sender }
    }
}

impl MailboxSender for TokioMailbox {
    fn send(&self, msg: Box<dyn Message>) -> BoxFuture<'static, ()> {
        self.sender.send(msg).map(|_| ()).boxed()
    }
}